#ifndef __CALL__HEADER__
#define __CALL__HEADER__

#include "paramconfig.h"
#include "common.h"

class SipCall
{
public:
    enum State
    {
        CALL_STATUS_NONE,       // UAC/UAS
        CALL_STATUS_CALLING,    // UAC
        CALL_STATUS_INCOMING,   // UAS
        CALL_STATUS_100Tring,   // UAC
        CALL_STATUS_180Ring,    // UAC
        CALL_STATUS_200OK,      // UAC
        CALL_STATUS_FAIL,       // UAC/UAS
        CALL_STATUS_INCALL,     // UAC/UAS
        CALL_STATUS_HANGUP,     // UAC/UAS
        CALL_STATUS_COMPLETE    // UAC/UAS
    };
    SipCall(eXosip_t* ctx, const ConfigParam& param);
    ~SipCall();

    void updateNatInfo(const std::string& nataddress, int natport);
    void updateNatAddress(const std::string& nataddress);
    void updateNatPort(int natport);

    bool sendOffer(const std::string& targetid, const std::string& sdp);
    bool sendAnswer(const std::string& sdp) { return true; }
    bool sendAck(int tid);
    void onOffer(int did, int cid, int tid);
    void on100();
    void on180();
    void onAnswer(int did, int cid, int tid);
    void onFail(int tid, int statuscode);
    void onAck();
    void terminate();

    bool sendCallRequest(const std::string& method, const std::string& contenttype, const std::string& msg, void* appdata = NULL);
    bool sendCallResponse(int tid, int statuscode, const std::string& contenttype, const std::string& msg);

    void transitionState(State s);
    bool success() const { return (mCallState == CALL_STATUS_INCALL); }
    bool isIncall() const;
protected:
    static std::string toString(State state);

    const ConfigParam&  mParam;
    eXosip_t*           mSipCtx;
    State               mCallState;
    int                 mDID;
    int                 mCID;
//     std::string         mNatAddress;
//     int                 mNatPort;
    char*               mNatAddress;
    char*               mNatPort;
};

#endif // #ifndef __CALL__HEADER__
